package com.salemanagement.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.nacos.api.naming.pojo.healthcheck.impl.Http;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.wxpay.sdk.WXPayUtil;
import com.salemanagement.mapper.*;
import com.salemanagement.service.OrderService;
import com.salemanagement.utils.HttpClient;
import com.salemanagement.vo.ProductOrderVo;
import com.salemanagement.vo.QueryParam;
import com.salemanagement.vo.StoreIncomeVO;
import com.salemanagement.vo.payResultVo;
import com.three.core.entity.*;
import com.three.core.vo.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl implements OrderService {
    private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);
    @Value("${weixin.appid}")
    private String appId;
    @Value("${weixin.mch_id}")
    private String mchId;
    @Value("${weixin.api_key}")
    private String apiKey;

    @Autowired
    private StoreMapper storeMapper;
    @Autowired
    private ProductOrderMapper productOrderMapper;
    @Autowired
    private UserIntegralMapper userIntegralMapper;
    @Autowired
    private UserIntegralLogMapper userIntegralLogMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private RabbitTemplate rabbitmqTest;
    @Autowired
    private OrderMapper orderMapper;

    @Override
    public R getAllOrder(QueryParam queryParam) {
        QueryWrapper<ProductOrder> queryWrapper = new QueryWrapper<>();
        // 处理日期参数（若为空则默认当前月）
        String month;
        if (StringUtils.isBlank(queryParam.getDate())) {
            // 默认当前月
            month = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
        } else {
            try {
                // 解析ISO时间并转换为本地时区（示例使用系统默认时区）
                Instant instant = Instant.parse(queryParam.getDate());
                ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
                // 提取年月（格式：yyyy-MM）
                month = zdt.format(DateTimeFormatter.ofPattern("yyyy-MM"));
            } catch (DateTimeParseException e) {
                logger.error("日期格式错误: {}", queryParam.getDate(), e);
                return new R<>(400, "日期格式错误，请使用ISO标准格式（如2025-03-31T16:00:00.000Z）", null);
            }
        }

        // 构建查询条件（当月范围）
        LocalDate startDate = LocalDate.parse(month + "-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endDate = startDate.withDayOfMonth(startDate.lengthOfMonth());
        queryWrapper.between("order_finish_time", startDate, endDate);

        if (StringUtils.isNotBlank(queryParam.getStoreName())) {
            queryWrapper.eq("store_name", queryParam.getStoreName());
        }

        // 打印查询条件
        logger.info("查询条件: {}", queryWrapper.getSqlSegment());
        List<ProductOrder> productOrders = productOrderMapper.selectList(queryWrapper);
        // 应用查询条件
        try {
            logger.info("查询结果数量: {}", productOrders.size());
        } catch (Exception e) {
            logger.error("查询订单列表时发生异常", e);
            return new R<>(500, "查询订单列表时发生异常", null);
        }

        // 获取订单列表
        // 按门店分组统计总金额
        Map<String, Double> storeSumMap = productOrders.stream()
                .collect(Collectors.groupingBy(
                        productOrder -> productOrder.getStoreName(),
                        Collectors.summingDouble(productOrder -> productOrder.getTotalAmount().doubleValue())
                ));

        // 提取门店名称和总金额列表
        List<String> storeNames = new ArrayList<>(storeSumMap.keySet());
        List<Double> sums = new ArrayList<>(storeSumMap.values());

        // 构造返回数据
        Map<String, Object> result = new HashMap<>();
        result.put("date", month);
        result.put("storeNames", storeNames);
        result.put("sums", sums);

        return new R<>(200, "查询成功", result);
    }

    @Override
    public R createWeChat(String orderNo) {
        QueryWrapper<ProductOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", orderNo);
        queryWrapper.eq("status_code", 11);
        ProductOrder productOrder = productOrderMapper.selectOne(queryWrapper);
        if (productOrder != null) {
            try {
                // 设置请求的参数--格式为xml格式
                Map<String, String> params = new HashMap<>();
                params.put("appid", appId);
                params.put("mch_id", mchId);
                params.put("nonce_str", WXPayUtil.generateNonceStr());
                params.put("body", productOrder.getProductName());
                params.put("out_trade_no", orderNo);
                params.put("total_fee", "1");
                params.put("spbill_create_ip", "127.0.0.1");
                params.put("notify_url", "http://www.baidu.com");
                params.put("trade_type", "NATIVE");

                // 打印参数值以检查
                logger.info("AppID: {}", appId);
                logger.info("MchID: {}", mchId);
                logger.info("ApiKey: {}", apiKey);

                // 创建HttpClientUtil对象 作用远程调用
                HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
                // 支持https协议
                client.setHttps(true);

                // 生成签名后的XML字符串
                String signedXml = WXPayUtil.generateSignedXml(params, apiKey);
                logger.info("Signed XML: {}", signedXml); // 打印生成的XML以检查

                // 设置请求体
                client.setXmlParam(signedXml);

                // 发送请求
                client.post();

                // 获取返回结果
                String xml = client.getContent();

                // 处理响应XML
                Map<String, String> responseMap = WXPayUtil.xmlToMap(xml);
                if ("SUCCESS".equals(responseMap.get("return_code")) && "SUCCESS".equals(responseMap.get("result_code"))) {
                    rabbitmqTest.convertAndSend("pt_exchange01", "dead.weixin", orderNo);
                    payResultVo result=new payResultVo(responseMap.get("code_url"),productOrder.getTotalAmount(),orderNo);
                    // 处理成功的逻辑
                    return new R<>(200, "支付请求成功", result);
                } else {
                    // 处理失败的逻辑
                    String errorCode = responseMap.get("err_code");
                    String errorMsg = responseMap.get("err_code_des");
                    return new R<>(500, "支付请求失败: " + errorCode + " - " + errorMsg, responseMap);
                }
            } catch (Exception e) {
                return new R<>(500, "创建微信支付订单时发生异常", null);
            }
        }
        return new R<>(505, "订单失效", null);
    }

    @Override
    public R queryWeChatPayStatus(String orderNo) {
        try {
            HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
            Map<String, String> params = new HashMap<>();
            params.put("appid", appId);
            params.put("mch_id", mchId);
            params.put("out_trade_no", orderNo);
            params.put("nonce_str", WXPayUtil.generateNonceStr());
            client.setHttps(true);
            client.setXmlParam(WXPayUtil.generateSignedXml(params, apiKey));
            client.post();
            String xml = client.getContent();
            Map<String, String> result = WXPayUtil.xmlToMap(xml);
            System.out.println("1."+result);
            if ("SUCCESS".equals(result.get("trade_state"))) {
                ProductOrder productOrder1 = productOrderMapper.selectByOrderNo(orderNo);
                if (productOrder1 != null) {
                    if (productOrder1.getProductId()==136) {
                        productOrder1.setStatusCode(43);
                    }else {
                        productOrder1.setStatusCode(41);
                    }
                    productOrder1.setPayTime(LocalDateTime.now());
                    QueryWrapper<ProductOrder> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("order_no", orderNo);
                    productOrderMapper.update(productOrder1, queryWrapper);
                        return new R<>(200, "支付成功", null);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return new R<>(505, "支付失败", null);
    }

    @Override
    public R<Product> PayFinish(Integer id) {
        ProductOrder productOrder = productOrderMapper.selectById(id);
        if (productOrder != null) {
            Product product = productMapper.selectByProductId(productOrder.getProductId());
            return new R<Product>(200, "支付成功", product);
        }
        return new R<>(505, "支付失败", null);
    }

    @Override
    public R IntegralPay(ProductOrderVo productOrderVo) {
        ProductOrder productOrder = productOrderMapper.selectByOrderNo(productOrderVo.getOrderNo());
        if (productOrder != null) {
            BigDecimal totalIntegral = productOrder.getTotalIntegral()
                    .multiply(new BigDecimal(productOrderVo.getProductCount().toString()));
            UserIntegral userIntegral = userIntegralMapper.selectIntegral(productOrderVo.getUserId(), productOrderVo.getStoreId());
            if (userIntegral.getCredits() >= totalIntegral.intValue()) {
                int update = userIntegralMapper.updateIntegral(productOrderVo.getUserId(), totalIntegral, productOrderVo.getStoreId());
                if (update > 0) {
                    int i = productOrderMapper.updateStatus(productOrderVo.getId());
                    if (i > 0) {
                        userIntegralLogMapper.insertLog(productOrderVo.getUserId(),totalIntegral,productOrderVo.getStoreId());
                        return new R<>(200, "兑换成功", null);
                    }
                 }
                    return new R<>(500, "兑换失败", null);
            }
                return new R<>(505, "积分不足", null);
        }
        return new R<>(505, "兑换失败", null);
    }

    @Override
    public R createWDPay(ProductOrderVo productOrderVo) {
        QueryWrapper<ProductOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order_no", productOrderVo.getOrderNo());
        queryWrapper.eq("status_code", 11);
        ProductOrder productOrder = productOrderMapper.selectOne(queryWrapper);
        if (productOrder != null) {
            BigDecimal totalIntegral = productOrder.getTotalIntegral();
            UserIntegral userIntegral = userIntegralMapper.selectIntegral(productOrderVo.getUserId(), productOrderVo.getStoreId());
            if (userIntegral.getCredits() >= totalIntegral.intValue()) {
                try {
                            // 设置请求的参数--格式为xml格式
                            Map<String, String> params = new HashMap<>();
                            params.put("appid", appId);
                            params.put("mch_id", mchId);
                            params.put("nonce_str", WXPayUtil.generateNonceStr());
                            params.put("body", productOrder.getProductName());
                            params.put("out_trade_no", productOrderVo.getOrderNo());
                            params.put("total_fee", "1");
                            params.put("spbill_create_ip", "127.0.0.1");
                            params.put("notify_url", "http://www.baidu.com");
                            params.put("trade_type", "NATIVE");

                            // 打印参数值以检查
                            logger.info("AppID: {}", appId);
                            logger.info("MchID: {}", mchId);
                            logger.info("ApiKey: {}", apiKey);

                            // 创建HttpClientUtil对象 作用远程调用
                            HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
                            // 支持https协议
                            client.setHttps(true);

                            // 生成签名后的XML字符串
                            String signedXml = WXPayUtil.generateSignedXml(params, apiKey);
                            logger.info("Signed XML: {}", signedXml); // 打印生成的XML以检查

                            // 设置请求体
                            client.setXmlParam(signedXml);

                            // 发送请求
                            client.post();

                            // 获取返回结果
                            String xml = client.getContent();
                            Map<String, String> responseMap = WXPayUtil.xmlToMap(xml);
                            if ("SUCCESS".equals(responseMap.get("return_code")) && "SUCCESS".equals(responseMap.get("result_code"))) {
                                rabbitmqTest.convertAndSend("pt_exchange01", "dead.weixin", productOrderVo.getOrderNo());
                                payResultVo result=new payResultVo(responseMap.get("code_url"),productOrder.getTotalAmount(),productOrderVo.getOrderNo());
                                    return new R<>(200, "支付请求成功", result);
                            } else {
                                // 处理失败的逻辑
                                String errorCode = responseMap.get("err_code");
                                String errorMsg = responseMap.get("err_code_des");
                                return new R<>(500, "支付请求失败: " + errorCode + " - " + errorMsg, responseMap);
                            }
                        } catch (Exception e) {
                            return new R<>(500, "创建微信支付订单时发生异常", null);
                        }
                    }
            return new R<>(500, "积分不足", null);
                    }
        return new R<>(505, "订单失效", null);
                }

    @Override
    public R queryWDPayStatus(ProductOrderVo productOrderVo) {
        try {
            HttpClient client = new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");
            Map<String, String> params = new HashMap<>();
            params.put("appid", appId);
            params.put("mch_id", mchId);
            params.put("out_trade_no", productOrderVo.getOrderNo());
            params.put("nonce_str", WXPayUtil.generateNonceStr());
            client.setHttps(true);
            client.setXmlParam(WXPayUtil.generateSignedXml(params, apiKey));
            client.post();
            String xml = client.getContent();
            Map<String, String> result = WXPayUtil.xmlToMap(xml);
            if ("SUCCESS".equals(result.get("trade_state"))) {
                ProductOrder productOrder = new ProductOrder();
                Product products = (Product) productMapper.selectByProductId(productOrderVo.getProductId());
                if (products.getProductId()==136){
                    productOrder.setStatusCode(43);
                }else {
                    productOrder.setStatusCode(41);
                }
                productOrder.setPayTime(LocalDateTime.now());
                QueryWrapper<ProductOrder> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("order_no", productOrderVo.getOrderNo());
                productOrderMapper.update(productOrder, queryWrapper);
                ProductOrder productOrder1 = productOrderMapper.selectOne(queryWrapper);
                BigDecimal totalIntegral = productOrder1.getTotalIntegral();
                int update = userIntegralMapper.updateIntegral(productOrder.getUserId(), totalIntegral, productOrder.getStoreId());
                if (update > 0) {
                    userIntegralLogMapper.insertLog(productOrderVo.getUserId(),totalIntegral,productOrderVo.getStoreId());
                }
                // 支付成功
                return new R<>(200, "支付成功", null);
            }
        }catch (Exception e){
            throw new RuntimeException(e);
        }
        return new R<>(505, "支付失败", null);
    }

    @Override
    public List<Map<String, Object>> getIncomeStatistics(String date, String storeName) {
        try {
            // 1. 日期处理
            String formattedDate = formatDate(date);
            
            // 2. 获取收入数据
            List<StoreIncomeVO> incomeData = orderMapper.findIncome(formattedDate, storeName);
            
            // 3. 转换数据格式
            return convertToResponseFormat(incomeData);
        } catch (Exception e) {
            logger.error("获取收入统计失败", e);
            throw new RuntimeException("获取收入统计失败: " + e.getMessage());
        }
    }

    /**
     * 格式化日期
     * @param date 输入日期字符串
     * @return 格式化后的日期字符串 (yyyy-MM)
     */
    private String formatDate(String date) {
        if (StringUtils.isBlank(date)) {
            return LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM"));
        }

        try {
            // 尝试解析日期
            LocalDate parsedDate;
            if (date.contains("T")) {
                // 处理 ISO 格式日期
                Instant instant = Instant.parse(date);
                parsedDate = instant.atZone(ZoneId.systemDefault()).toLocalDate();
            } else {
                // 处理普通日期格式，假设输入格式为 yyyy-MM
                parsedDate = LocalDate.parse(date + "-01");
            }
            return parsedDate.format(DateTimeFormatter.ofPattern("yyyy-MM"));
        } catch (DateTimeParseException e) {
            logger.error("日期格式解析错误: {}", date, e);
            throw new IllegalArgumentException("日期格式不正确，请使用 yyyy-MM 格式");
        }
    }

    /**
     * 转换数据为前端所需格式
     * @param incomeData 收入数据列表
     * @return 转换后的数据
     */
    private List<Map<String, Object>> convertToResponseFormat(List<StoreIncomeVO> incomeData) {
        if (incomeData == null || incomeData.isEmpty()) {
            return new ArrayList<>();
        }

        return incomeData.stream()
            .map(vo -> {
                Map<String, Object> item = new HashMap<>(2);
                item.put("storeName", vo.getStoreName() != null ? vo.getStoreName() : "未知商家");
                item.put("sum", vo.getSum() != null ? vo.getSum() : BigDecimal.ZERO);
                return item;
            })
            .collect(Collectors.toList());
    }

    @Override
    public List<Map<String, Object>> getAllStores() {
        try {
            return orderMapper.selectAllStores();
        } catch (Exception e) {
            logger.error("获取商店列表失败", e);
            return new ArrayList<>();
        }
    }
}